import random
from django.contrib.auth.hashers import make_password, check_password
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django.views.decorators.http import require_http_methods
from captcha.image import ImageCaptcha

from organization.models import OrganizationModel, NoticeModel
from student.models import StudentModel, Subscription
from supervisor.models import InternshipPosting, InterviewSchedule, JobPosting

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

count_loging = 0  # 统计尝试登录的次数


# Create student views here.
class RegisterView(View):
    """ 学生注册 """

    def get(self, request):
        """ get请求提供用户注册界面 """
        return render(request, 'register/student_register.html')

    def post(self, request):
        """ post请求实现学生注册业务逻辑 """
        # # 对密码加密
        encrypt_pwd = make_password(request.POST.get('password'))
        # 向数据库添加一条学生数据
        StudentModel.objects.create(
            stu_name=request.POST.get('stu_name'),
            password=encrypt_pwd,  # 开启密码加密
            stu_num=request.POST.get('stu_num'),
            gender=request.POST.get('gender'),
            email=request.POST.get('email'),
            phone_number=request.POST.get('phone_number'),
            department=request.POST.get('department')
        )

        result_data = {'code': 200}
        return JsonResponse(result_data)


@require_http_methods(['POST'])
def check_number(request):
    """ 验证学生是否唯一 """
    result_data = {}
    # {'valid': True} 如果返回的是Ture: 表示验证合法，通过
    # {'valid': False} 如果返回的是False: 表示验证非法，不通过
    stu_num = request.POST.get('stu_num')  # 接受请求参数
    user = StudentModel.objects.filter(stu_num=stu_num)
    if user:
        # 已经存在一个学号相同的用户
        result_data['valid'] = False
        return JsonResponse(result_data)
    else:
        # 学号不重复就返回真
        result_data['valid'] = True
        return JsonResponse(result_data)


class LoginView(View):
    """ 学生登录 """

    def get(self, request):
        """ get请求提供学生登录界面 """
        return render(request, 'login/student_login.html')

    def post(self, request):
        """ post请求实现学生登录业务逻辑 """
        global count_loging
        try:
            if not request.COOKIES.get('user_locked'):  # 如果没有被封，才进行判断登录次数
                if count_loging < 4:  # 判断登录次数
                    count_loging += 1  # 每登录一次，次数加一
                    stu_num = request.POST.get('stu_num')  # 得到学号
                    password = request.POST.get('password')  # 根据原始密码
                    # 根据学号找到相应的学生，并比较密码
                    student = StudentModel.objects.get(stu_num=stu_num)
                    encrypt_pwd = student.password
                    if check_password(password, encrypt_pwd):   # 当密码正确时写入cookie
                        # 检测是否通过管理员审核
                        if not student.check_status:
                            return JsonResponse({'code': 403})  # 审核中
                        # 返回200状态码，前端JS会自动跳转到首页
                        result_data = {'code': 200}
                        response = JsonResponse(result_data)
                        # 登录成功在cookie中写入is_login已登录标志
                        response.set_cookie("user_status", "is_login")
                        # 并且创建一个session，将tch_num装进去
                        request.session['user_id'] = stu_num
                        return response  # 账号密码正确就进入系统
                    else:
                        result_data = {'code': 401}  # 错误的话返回401标识账号密码错误
                        return JsonResponse(result_data)
                else:
                    # 登录尝试超过5次，就会设置一个cookie记录封禁的时长
                    result_data = {'code': 402}  # 402错误标识为输入次数过多
                    response = JsonResponse(result_data)
                    response.set_cookie("user_locked", "True", max_age=60*5)  # 这里max_age=封多久，60*5代表5分钟
                    count_loging = 0
                    return response
            else:
                result_data = {'code': 402}  # 402错误标识为输入次数过多
                response = JsonResponse(result_data)
                return response
        except:
            result_data = {'code': 401}
            return JsonResponse(result_data)


# 学生的home
def home(request):
    # 学生不同功能页面也不同
    # 从session中取出当前用户的id
    stu_num = user_id = request.session.get('user_id')
    # 用户可能是学生1，企业2，管理员3，用if语句来判断
    organization = OrganizationModel.objects.filter(email=user_id)
    student = StudentModel.objects.filter(stu_num=user_id)
    if organization.exists():
        user_label = 2
        organization = organization[0]
    elif student.exists():
        user_label = 1
        student = student[0]
    else:
        user_label = 3

    # 查询出这个学生的所有预约
    internship = InternshipPosting.objects.filter(student=student)
    interview = InterviewSchedule.objects.filter(student=student)

    # 查询出这个学生关注的企业是否有新的通知
    subscriptions = Subscription.objects.filter(student=student)
    notices = NoticeModel.objects.filter(publisher__in=[sub.organization for sub in subscriptions])
    print(notices)
    # 将数据渲染到前端HTML模版里
    return render(request, 'home_page/student_index.html', locals())



@require_http_methods(['GET'])
def generate_code(request):
    # 生成随机的4位数字与字母组合的验证码
    captcha_str = ''.join(random.sample('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 4))
    # 生成验证码图片
    image = ImageCaptcha().generate_image(captcha_str)
    # 将验证码存入session，方便后续验证
    request.session['verify_code'] = captcha_str
    # 将验证码图片以PNG格式返回给前端
    response = HttpResponse(content_type='image/png')
    image.save(response, 'PNG')
    return response


@require_http_methods(['POST'])
def verify_code(request):
    """验证: 验证码是否正确"""
    # {'valid': True} 如果返回的是Ture: 表示验证合法，通过
    # {'valid': False} 如果返回的是False: 表示验证非法，不通过
    result_data = {'valid': True}  # 先定义一个默认的返回参数
    code1 = request.POST.get('captcha')  # 接受请求参数
    # 服务器里面在前一次请求的时候就已经存了验证码：
    code2 = request.session['verify_code']
    if not code1.lower() == code2.lower():
        # 客户端的验证码写错了
        result_data['valid'] = False
    return JsonResponse(result_data)

# 展示就业招牌岗位信息
class ShowJobView(View):

    def get(self, request):
        # 获取当前登录用户的id
        user_id = request.session.get('user_id')
        # 通过id找到当前登录用户
        # 用户可能是学生1，企业2，管理员3，用if语句来判断
        organization = OrganizationModel.objects.filter(email=user_id)
        student = StudentModel.objects.filter(stu_num=user_id)
        if organization.exists():
            user_label = 2
            organization = organization[0]
        elif student.exists():
            user_label = 1
            student = student[0]
        else:
            user_label = 3
        # 找到所有招聘信息
        job_postings = JobPosting.objects.all()
        return render(request, 'job_posting/show-jobs.html', locals())


class CreateInterviewView(View):

    def post(self, request):
        try:
            data = request.POST
            # 获得了学生的id、企业的id、岗位的id，根据三个信息查找到三个对象，并生成面试预约表
            # 获取当前登录用户的id
            user_id = request.session.get('user_id')
            student = StudentModel.objects.filter(stu_num=user_id)[0]
            job_posting = JobPosting.objects.filter(id=data.get('job_id'))[0]
            InterviewSchedule.objects.create(
                student=student,
                job_posting=job_posting,
                organization=job_posting.organization,
                interview_date=timezone.now(),
                interview_mode='待确认',
                location='待确认',
                status='pending'
            )
            return JsonResponse({'code': 200})
        except Exception as e:
            print(e)
            return JsonResponse({'code': 500})



class InterviewListView(View):
    def get(self, request):
        # 获取当前登录用户的id
        user_id = request.session.get('user_id')
        # 通过id找到当前登录用户
        # 用户可能是学生1，企业2，管理员3，用if语句来判断
        organization = OrganizationModel.objects.filter(email=user_id)
        student = StudentModel.objects.filter(stu_num=user_id)
        if organization.exists():
            user_label = 2
            organization = organization[0]
        elif student.exists():
            user_label = 1
            student = student[0]
        else:
            user_label = 3
        # 找到与该学生有关的面试信息
        interview_schedules = InterviewSchedule.objects.filter(student=student)

        return render(request, 'interview/student-interview.html', locals())


class InternshipListView(View):
    def get(self, request):
        # 获取当前登录用户的id
        user_id = request.session.get('user_id')
        # 通过id找到当前登录用户
        # 用户可能是学生1，企业2，管理员3，用if语句来判断
        organization = OrganizationModel.objects.filter(email=user_id)
        student = StudentModel.objects.filter(stu_num=user_id)
        if organization.exists():
            user_label = 2
            organization = organization[0]
        elif student.exists():
            user_label = 1
            student = student[0]
        else:
            user_label = 3
        # 找到与该学生有关的实习表
        internships = InternshipPosting.objects.filter(student=student)


        return render(request, 'internship/student-internship.html', locals())


class SubscriptionOrganization(View):
    """
    处理用户对企业订阅操作的视图类。

    方法:
    - get: 获取企业信息并渲染到指定模板。
    - post: 处理用户的订阅请求。
    """

    def get(self, request):
        """
        获取企业信息并展示给用户。

        参数:
        - request: HttpRequest对象，包含客户端请求的数据和信息。

        返回:
        - HttpResponse对象，渲染的企业信息页面。
        """
        # 获取登录用户ID
        user_id = request.session.get('user_id')
        # 通过GET请求获取企业名称
        org_name = request.GET.get('org_name')

        # 根据企业名称和用户ID查找对应的组织和学生信息
        organization = OrganizationModel.objects.filter(name=org_name)[0]
        student = StudentModel.objects.filter(stu_num=user_id)[0]
        user_label = 1  # 用户标签，此处未使用但保留可能的用途

        # 将信息传递给模板并返回渲染结果
        return render(request, 'subscription/get-company-info.html', locals())

    def post(self, request):
        """
        处理用户的订阅操作。

        参数:
        - request: HttpRequest对象，包含客户端请求的数据和信息。

        返回:
        - JsonResponse对象，包含订阅操作的结果信息。
        """
        # 获取登录用户ID
        user_id = request.session.get('user_id')
        # 根据用户ID查找学生信息
        student = StudentModel.objects.filter(stu_num=user_id)[0]
        # 从POST请求中获取企业邮箱
        email = request.POST.get('email')
        # 根据邮箱查找对应的组织信息
        organization = OrganizationModel.objects.filter(email=email)[0]

        # 检查用户是否已经订阅了该企业
        if Subscription.objects.filter(student=student, organization=organization).exists():
            # 如果已订阅，则返回提示信息
            return JsonResponse({'code': '已关注！'})
        else:
            # 如果未订阅，则创建新的订阅记录
            Subscription.objects.create(
                student=student,
                organization=organization,
            )
            # 打印订阅信息（供调试使用）
            # print(student, '关注了', organization)
            # 返回订阅成功的提示信息
            return JsonResponse({'code': '关注成功！'})


class RecommendOrganization(View):

    def get(self, request):
        # 获取当前登录用户的id
        user_id = request.session.get('user_id')

        # 通过id找到当前登录用户
        # 用户可能是学生1，企业2，管理员3
        organization = OrganizationModel.objects.filter(email=user_id)
        student = StudentModel.objects.filter(stu_num=user_id)
        if organization.exists():
            user_label = 2
            organization = organization[0]
        elif student.exists():
            user_label = 1
            student = student[0]
        else:
            user_label = 3

        return render(request, 'recommend/recommend.html', locals())

    def post(self, request):
        intention = request.POST.get('intention')
        print(f'{intention = }')
        job_postings = JobPosting.objects.all()

        # 初始化vectorizer
        vectorizer = TfidfVectorizer()
        # 创建一个列表来保存工作岗位详情,并包括就业意向
        job_details = [intention]

        # 通过招聘职位来创建工作细节字符串
        for job in job_postings:
            job_detail_string = f"{job.title} {job.description} {job.requirements} {job.salary_range} {job.location}"
            job_details.append(job_detail_string)

        print(f'{job_details = }')
        # 将文本转换为矢量形式
        tfidf_matrix = vectorizer.fit_transform(job_details)
        # 计算意向和所有工作职位之间的余弦相似性
        cosine_similarities = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix[1:]).flatten()
        # 找到职位索引的最高相似度
        max_similarity_index = cosine_similarities.argmax()

        # 获得最类似的职位职位
        most_similar_job = job_postings[int(max_similarity_index)]
        print(f'{most_similar_job = }')

        # 获取当前登录用户的id
        user_id = request.session.get('user_id')

        # 通过id找到当前登录用户
        # 用户可能是学生1，企业2，管理员3
        organization = OrganizationModel.objects.filter(email=user_id)
        student = StudentModel.objects.filter(stu_num=user_id)
        if organization.exists():
            user_label = 2
            organization = organization[0]
        elif student.exists():
            user_label = 1
            student = student[0]
        else:
            user_label = 3

        return render(request, 'recommend/recommend.html', locals())
